package com.example.dbsample.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dbsample.annotation.StopWatchPrint;
import com.example.dbsample.config.multithread.AsyncConfig;
import com.example.dbsample.context.ThreadLocalContext;
import com.example.dbsample.mapper.SysDictDataMapper;
import com.example.dbsample.model.entity.SysDictData;
import com.example.dbsample.model.http.ResultCode;
import com.example.dbsample.service.business.SysDictDataService;
import com.example.dbsample.util.date.DateUtils;
import com.example.dbsample.util.factory.AutoCreate;
import org.apache.commons.lang.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@AutoCreate("1")
public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData> implements SysDictDataService {

    @Override
    public SysDictData querySysDictDataEntity() {

        return baseMapper.selectById(2);
    }

    /**
     * QueryWrapper查询
     * TODO 注：因为是异步操作，故返回值为null
     * @return
     */
    @Override
    @Async(AsyncConfig.TASK_BEAN)
    @StopWatchPrint
    public List<SysDictData> querySysDictDataEntityByQueryWrapper(int isDeleted) {
        System.out.println("再次进入方法：querySysDictDataEntityByQueryWrapper(...)");
        return baseMapper.selectList(new QueryWrapper<SysDictData>().lambda()
                .eq(SysDictData::getDeleted, isDeleted)
                .orderByAsc(SysDictData::getCreateTime)
                .last(" limit " + 10));
    }

    /**
     * LambdaQueryWrapper查询
     * @return
     */
    @Override
    public List<SysDictData> querySysDictDataEntityByLambdaQueryWrapper() {
        System.out.println("再次进入方法：querySysDictDataEntityByQueryWrapper(...)");

        return baseMapper.selectList(new LambdaQueryWrapper<SysDictData>()
                .le(SysDictData::getUpdateTime, new Date())
                .lt(SysDictData::getUpdateTime, new Date())
                .gt(SysDictData::getUpdateTime, DateUtils.parse("2024-01-06 20:28:14", DateUtils.DATE_TIME_PATTERN))
                .ge(SysDictData::getUpdateTime, DateUtils.parse("2024-01-06 20:28:14", DateUtils.DATE_TIME_PATTERN))
                .eq(SysDictData::getDeleted, 0)
                .notIn(SysDictData::getDeleted, Arrays.asList(1, 2))
                .select(SysDictData.class, info -> info.getColumn().equals("dict_type_id"))       // 选择这一列
                //.isNull(SysDictData::getRemark)
                .isNotNull(SysDictData::getLabelClass)
                .last(" limit " + 10));
    }

    /**
     * 分页查询 - QueryWrapper
     * TODO 疑似无用
     * @return
     */
    @Override
    public ResultCode<IPage<SysDictData>> querySysDictDataEntityByQueryWrapperPage() {
        System.out.println("进入方法：querySysDictDataEntityByLambdaQueryWrapperPage(...)");

        int currentPage = 1;
        int pageSize = 10;
        Page<SysDictData> page = new Page<>(currentPage++, pageSize);
        IPage<SysDictData> pageResult =
                baseMapper.selectPage(page, new QueryWrapper<SysDictData>().lambda().eq(SysDictData::getDeleted, 0)
        );
        System.out.println(pageResult.getRecords().size());
        return new ResultCode<IPage<SysDictData>>().success(pageResult);
    }

    /**
     * 分页查询 - LambdaQueryWrapper
     * TODO 疑似无用
     * @return
     */
    @Override
    public ResultCode<IPage<SysDictData>> querySysDictDataEntityByLambdaQueryWrapperPage() {
        System.out.println("进入方法：querySysDictDataEntityByLambdaQueryWrapperPage(...)");

        LambdaQueryWrapper<SysDictData> wrapper = Wrappers.lambdaQuery(SysDictData.class);
        wrapper.eq(SysDictData::getDeleted, 0);

        Page<SysDictData> page = new Page<>(1, 5);
        IPage<SysDictData> pageResult = baseMapper.selectPage(page, wrapper);
        System.out.println(pageResult.getRecords().size());
        return new ResultCode<IPage<SysDictData>>().success(pageResult);
    }

    @Override
    public ResultCode<Page<SysDictData>> querySysDictDataEntityByLambdaQueryWrapperPageV2() {
        System.out.println("进入方法：querySysDictDataEntityByLambdaQueryWrapperPageV2(...)");

        //LambdaQueryWrapper<SysDictData> wrapper = Wrappers.lambdaQuery(SysDictData.class);
        QueryWrapper<SysDictData> wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", 0L);

        Page<SysDictData> page = new Page<>(2, 5);

        // 加查询条件
        Page<SysDictData> pageResult = this.page(page, wrapper);
        return new ResultCode<Page<SysDictData>>().success(pageResult);
    }

    @Override
    public ResultCode<Page<SysDictData>> querySysDictDataEntityByLambdaQueryWrapperPageAll() {
        System.out.println("进入方法：querySysDictDataEntityByLambdaQueryWrapperPageV2(...)");

        Page<SysDictData> page = new Page<>(2, 5);

        // 不加查询条件，就是查询所有
        Page<SysDictData> pageResult = this.page(page);
        return new ResultCode<Page<SysDictData>>().success(pageResult);
    }

    @Override
    public int updateSysDictDataEntityByQueryWrapper() {
        System.out.println("再次进入方法：updateSysDictDataEntityByQueryWrapper(...)");

        List<SysDictData> SysDictDataList = baseMapper.selectList(new QueryWrapper<SysDictData>().lambda()
                .eq(SysDictData::getDeleted, 0)
                .last(" limit " + 10));

        if(CollectionUtils.isEmpty(SysDictDataList)) {
            return -1;
        }

        SysDictData sysDictData = SysDictDataList.get(0);
        sysDictData.setUpdateTime(new Date());

        int result = this.baseMapper.update(sysDictData,
                new QueryWrapper<SysDictData>().lambda()
                        .eq(SysDictData::getId, 10L)
                        .or()
                        .eq(SysDictData::getDeleted, 0));

        return result;
    }
    @Override
    public SysDictData selectOneSysDictDataEntity() {
        System.out.println("再次进入方法：selectOneSysDictDataEntity(...)");

        SysDictData sysDictData = baseMapper.selectOne(new QueryWrapper<SysDictData>().lambda()
                //.ge(SysDictData::getUpdateTime, )
                //.le(SysDictData::getUpdateTime, )
                .eq(SysDictData::getId, 1));


        return sysDictData;
    }

    @Override
    public Integer batchSave(List<SysDictData> list) {
        Integer result = baseMapper.batchSave(list);

        return result;
    }
    @Override
    public Integer batchSaveV2(List<SysDictData> list) {
        Integer result = baseMapper.batchSaveV2(list);

        return result;
    }

    @Override
    public Integer batchUpdate(List<SysDictData> list) {
        Integer result = baseMapper.batchUpdate(list);

        return result;
    }

    @Override
    public Integer batchDeleteByIdList(List<Long> idList) {
        Integer result = baseMapper.batchDeleteByIdList(idList);

        return result;
    }

    @Override
    public int countByidList(List<Long> idList) {
        int result = baseMapper.countByidList(idList);
        return result;
    }

    @Override
    public List<SysDictData> selectByCondition(SysDictData sysDictData, int offset, int size, List<Integer> versionList) {
        return baseMapper.selectByCondition(sysDictData, offset, size, versionList);
    }


    @Override
    public List<SysDictData> selectByConditionV2(SysDictData sysDictData, int offset, int size, List<Integer> versionList) {
        return baseMapper.selectByConditionV2(sysDictData, offset, size, versionList);
    }

    @Override
    public List<SysDictData> selectNoNull(String labelClass, int offset, int size) {
        LambdaQueryWrapper<SysDictData> wrapper = Wrappers.lambdaQuery();
        // .setLabelClass("danger");
        wrapper.eq(StringUtils.isNotBlank(labelClass), SysDictData::getLabelClass, labelClass);
        Page<SysDictData> page = new Page<>(offset, size);
        Page<SysDictData> sysDictDataPage = baseMapper.selectPage(page, wrapper);
        List<SysDictData> versionList = new ArrayList<>();
        versionList = sysDictDataPage.getRecords();
        return versionList;
    }

    /**
     * TODO 这里没有实际删除
     * @return
     */
    @Override
    public int deleteByIdList() {
        List<Long> idList = new ArrayList<>();
        idList.add(34L);
        idList.add(35L);
        return baseMapper.delete(new QueryWrapper<SysDictData>().lambda().in(SysDictData::getId, idList));
    }

    // TODO 奇怪，4L、5L都没查到，明明DB里面有值
    /**
     * exits用法
     */
    @Override
    public boolean checkExists() {
        List<Long> idList = new ArrayList<>();
        idList.add(4L);
        idList.add(5L);
        boolean exists = false;
                //this.exists(new QueryWrapper<SysDictData>().lambda().in(SysDictData::getId, idList));
        return exists;
    }

    /**
     * 注意点：
     * 1. ThreadLocalContext
     * 2. Lists.newArrayList
     * 3. lambdaQuery()
     * 4. Arrays.asList(dictLabel.split(","))
     *
     * @param isDeleted
     * @return
     */
    @Override
    public HashSet<String> findSysDictDataVarialbes(int isDeleted) {
        ThreadLocalContext.setUserInfo("BIZ_CODE", "biz_code_value");
        String userId = ThreadLocalContext.getUserId();
        Long longUserId = Long.valueOf(userId);
        Long longUserIdV2 = 22L;
        List<Long> idList = Arrays.asList(1L, 2L, 3L, 19L, 20L, 21L);
        // TODO 要用包：com.google.common.collect.Lists
        //Lists.newArrayList(longUserIdV2, 11L));
        List<SysDictData> sysDictDataList =
                this.list(Wrappers.<SysDictData>lambdaQuery().in(SysDictData::getId, idList));
        HashSet<String> columns = new HashSet<>();
        sysDictDataList.stream().filter(t -> org.springframework.util.StringUtils.hasText(t.getDictValue())).forEach(sysDictData -> {
            String dictLabel = sysDictData.getDictLabel();
            columns.addAll(Arrays.asList(dictLabel.split(",")));
        });
        return columns;
    }
}
